package com.fifth.sso.config;

import com.fifth.sso.relam.BusinessRealm;
import com.fifth.sso.relam.EmpRealm;
import com.fifth.sso.relam.UserRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @program: qy151-springboot-shiro
 * @description:
 * @author: 闫克起2
 * @create: 2022-08-05 11:12
 **/
@Configuration
public class ShiroConfig {


    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setAuthenticator(modularRealmAuthenticator());
        List<Realm> realms = new ArrayList<>();
        // 用户登录
        realms.add(userRealm());
        // 商户登录
        realms.add(businessRealm());
        // 管理员登录
        realms.add(empRealm());

        securityManager.setRealms(realms);
        return securityManager;

    }

    @Bean("myModularRealmAuthenticator")
    public MyModularRealmAuthenticator modularRealmAuthenticator() {
        MyModularRealmAuthenticator customizedModularRealmAuthenticator = new MyModularRealmAuthenticator();
        // 设置realm判断条件
        customizedModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());

        return customizedModularRealmAuthenticator;
    }

    @Bean
    public Realm userRealm(){
        UserRealm userRealm=new UserRealm();
        userRealm.setCredentialsMatcher(credentialsMatcher());
        return userRealm;
    }

    @Bean
    public Realm empRealm(){
        EmpRealm empRealm=new EmpRealm();
        empRealm.setCredentialsMatcher(credentialsMatcher());
        return empRealm;
    }

    @Bean
    public Realm businessRealm(){
        BusinessRealm businessRealm = new BusinessRealm();
        businessRealm.setCredentialsMatcher(credentialsMatcher());
        return businessRealm;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5"); //MD5不安全。
        credentialsMatcher.setHashIterations(1024);
        return credentialsMatcher;
    }

    @Bean(value = "shiroFilter")
    public ShiroFilterFactoryBean filterFactoryBean(){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager());

        //设置拦截规则
        HashMap<String,String> map=new HashMap<>();
        map.put("/sso/loginOut","anon");
        map.put("/sso/isLoginAndBusiness","anon");
        map.put("/sso/login","anon");
        map.put("/doc.html","anon");
        map.put("/swagger-ui.html", "anon");
        map.put("/webjars/**", "anon");
        map.put("/swagger-resources/**", "anon");
        map.put("/swagger/**", "anon");
        map.put("/swagger2/**", "anon");
        map.put("/v2/**", "anon");
        map.put("/**","authc");
        map.put("/sso/sign","anon");
        factoryBean.setFilterChainDefinitionMap(map);

        //设置自定义认证过滤器
//        HashMap<String,Filter> filterMap=new HashMap<String, Filter>();
//        filterMap.put("authc",new LoginFilter());
//        factoryBean.setFilters(filterMap);

        return factoryBean;
    }

    @Bean //注册filter
    public FilterRegistrationBean<Filter> filterRegistrationBean(){
        FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    //开始shiro注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}
